#include "back.h"
#include "global.h"
#include "manager.h"


back::back(){
}

back::~back(){
	close();
}

void back::setManager(manager * m){
	boss = m;
}

void back::input(){
	int len = tcp.recv(buffer, 10240);
	if( len == 0 ){
		if( tcp.getRevStatus() < 0 ){
			boss->closeConn();
			return ;
		}
		return ;
	}else if (len < 0){
		boss->closeConn();
		return ;
	}else if( len > 0 ){
		if (boss->sendToFront(buffer, len) < 0){
			boss->closeConn();
			return ;
		}
	}
}
void back::output(){
	if (send_only_buffer() < 0){
		boss->closeConn();
		return ;
	}
}

int back::setAddrInfo(const string&ip, int port){
	backip = ip;
	backport = port;
	return 0;
}

int back::connect(const string &ip, int port){
	if( tcp.open() < 0){
		return -1;
	}

	tcp.setTimeOut(GLOBAL::back_timeout);
	//tcp.setNonBlock();

	if( tcp.connect(ip.c_str(), port) < 0){
		return -2;
	}
	
    event_set(&netEvent, tcp.getFd(), EV_READ | EV_PERSIST , dataInput, (void *)this);  
	event_add(&netEvent, NULL); 
	return 0;
}

int back::send(const char* msg, int msg_len){
	if( tcp.getFd() < 0 ){
		if( connect(GLOBAL::backIP, backport) < 0){
			return -1;
		}
	}
	int ret = 0;
	
	if( w_buf.size() > 0){
		w_buf.pushData(msg, msg_len);
		ret = tcp.send(w_buf.getBufferPtr(), w_buf.size());
		//::send(netfd, w_buf.getBufferPtr(), w_buf.size(), 0);
		if( ret < 0 ){
			return ret;
		}else{
			if( ret <= w_buf.size() ){
				w_buf.skipData(ret);
			}
		}
	} else{
		ret = tcp.send(msg, msg_len);
		if( ret <= 0 ){
			return ret;
		}else if( ret < msg_len ){
			w_buf.pushData(msg+ret, msg_len-ret);
		}
	}
	if( w_buf.size() > 0 ){
		_openWrite();
	}
	return ret;
}

int back::send_only_buffer(){
	if( tcp.getFd() < 0 ){
		return -1;
	}
	if( w_buf.size() <= 0 ){// TODO if < 0 the buffer is error now
		return 0;
	}
	int ret = tcp.send(w_buf.getBufferPtr(), w_buf.size());
	//::send(netfd, w_buf.getBufferPtr(), w_buf.size(), 0);
	if( ret < 0 ){
		return ret;
	}else if( ret == 0 ){
		return 0;
	}
	if( ret > w_buf.size() ){
		return -1;
	}
	w_buf.skipData(ret);
	if( w_buf.size() <= 0 ){
		_closeWrite();
	}
	return 0;
	
}

void back::_openWrite(){
	event_del(&netEvent); 
	event_set(&netEvent, tcp.getFd(), EV_READ | EV_WRITE | EV_PERSIST , dataInput, (void *)this);  
	event_add(&netEvent, NULL); 
}

void back::_closeWrite(){
	event_del(&netEvent); 
	event_set(&netEvent, tcp.getFd(), EV_READ | EV_PERSIST , dataInput, (void *)this);  
	event_add(&netEvent, NULL); 
}


void back::close(){
	tcp.close();// TODO is real want add it??
}


